#include<iostream>
#include<vector>
using namespace std;

template<class T>//class可以用typename替换，类模板一般用class；
class varray
{
public:
    varray();
    ~varray();

    //实现获取当前元素的个数
    int size() const;
    //实现获取当前数组的最大容量
    int capacity() const;
    //实现判断当前数组是否为空
    bool empty() const;


    //实现vector中的尾插法
    void push_back(const T &value);
    //实现vector中的尾删法
    void pop_back(const T &value); 
    //实现vector中的扩展最大容量
    void reserve(int n);
    //实现vector中的缩小和扩展容量并赋值
    void resize(int n);
    //实现删除数组中所有元素
    void clear();


    //实现vector中的at方法
    T &at(int index);
    //实现vector中的【】运算符重载
    T &operator[] (int index);
    //实现vector中的获取首个对象的常应用
    T &front();
    //实现vector中的获取最后一个对象的常应用
    T &back();


    //测试方法，输出当前数组元素的内容
    void show() const;

private:
    T *start;//数组第一个值的指针
    int finish;//数组的当前长度,即数组的元素个数
    int end_of_storage;//可增长的最大容量

};

template<class T>
varray<T>::varray() : start(nullptr),finish(0),end_of_storage(0)
{
}

template<class T>
varray<T>::~varray()
{
    if(start != nullptr)//判断是否有内容
    {
        delete []start;
        start = nullptr;
    }
    finish = 0;
    end_of_storage = 0;
}

//获取元素个数实现
template<class T>
int varray<T>::size() const
{
    return finish;
}

//获取当前的数组的最大容量实现
template<class T>
int varray<T>::capacity() const
{
    return end_of_storage;
}

//判断是否为空的实现
template<class T>
bool varray<T>::empty() const
{
    return finish == 0;
}

//尾插法实现
template<class T>
void varray<T>::push_back(const T &value)
{
    //判断是否有多余空间添加元素
    if(finish < end_of_storage)
    {
        start[finish] = value;
        finish++;
        return;
    }
    if(end_of_storage == 0)
    {
        end_of_storage = 1;
    }
    else
    {
        end_of_storage *= 2;//扩容，每次扩容两倍
    }
    T *data = new T[end_of_storage];
    for(int i = 0; i < finish; i++)
    {
        data[i] = start[i];//将原数组复制到新数组中
    }
    if(start != nullptr)
    {
        delete []start;
        start = nullptr;
    }
    start = data;
    start[finish] = value;
    finish++;
    return;
}

//尾删法实现
template<class T>
void varray<T>::pop_back(const T &value)
{
    if(finish > 0)
    {
        finish--;
    }
    else
    {
        cout << "no data in this varray!" << endl;
    }
}

//扩展当前最大容量
template<class T>
void varray<T>::reserve(int n)
{
    if(end_of_storage > n)
    {
        return;
    }
    while (end_of_storage < n)
    {
        if(end_of_storage == 0)
        {
            end_of_storage = 1;
        }
        else
        {
            end_of_storage *= 2;
        }
    }
    T *data = new T[end_of_storage];
    for(int i = 0; i < finish; i++)
    {
        data[i] = start[i];//将原数组复制到新数组中
    }
    if(start != nullptr)
    {
        delete []start;
        start = nullptr;
    }
    start = data;
}

//扩展或者缩小容量实现
template<class T>
void varray<T>::resize(int n)
{
    if(finish >= n)
    {
        finish = n;
        return;
    }
    if(n <= end_of_storage)
    {
        for(int i = finish; i < n; i++)
        {
            start[i] = T();
        }
        finish = n;
        return;
    }
    while (end_of_storage < n)
    {
        if(end_of_storage == 0)
        {
            end_of_storage = 1;
        }
        else
        {
            end_of_storage *= 2;
        }
    }
    T *data = new T[end_of_storage];
    for(int i = 0; i < finish; i++)
    {
        data[i] = start[i];//将原数组复制到新数组中
    }
    for(int i = finish; i < n; i++)
    {
        start[i] = T();
    }
    finish = n;
    if(start != nullptr)
    {
        delete []start;
        start = nullptr;
    }
    start = data;
}

//删除数组中所有元素实现
template<class T>
void varray<T>::clear()
{
    finish = 0;
}

//at方法实现
template<class T>
T &varray<T>::at(int index)
{
    if(index < 0 || index >= finish)
    {
        cout << "index no in this varray!" << endl;
    }
    return start[index];
}

//【】运算符重载实现
template<class T>
T &varray<T>::operator[] (int index)
{
    return at(index);
}

//实现vector中的获取首个对象的常应用
template<class T>
T &varray<T>::front()
{
    if(finish <= 0)
    {
        cout << "no data in this varray!" << endl;
    }
    return start[0];
}

//实现vector中的获取最后一个对象的常应用
template<class T>
T &varray<T>::back()
{
    if(finish <= 0)
    {
        cout << "no data in this varray!" << endl;
    }
    return start[finish - 1];
}

//测试方法实现
template<class T>
void varray<T>::show() const
{
    cout << "size=" << size() << ",";
    cout << "capacity=" << capacity() << endl;
    for(int i = 0;i < finish; i++)
    {
        cout << start[i] << " ";
    }
    cout << endl;
}

int main()
{
    varray<int> a;
    cout << "Now data is(1为空，0为有数据)(调用empty):" << a.empty() << endl;
    a.push_back(1);
    a.push_back(2);
    a.push_back(3);
    a.push_back(4);
    a.show();
    cout << "插入数据5后数组内容(调用push_back)：" << endl;
    a.push_back(5);
    a.show();
    cout << "删除数据5后数组内容(调用pop_back)：" << endl;
    a.pop_back(4);
    a.show();

    cout << "扩展最大容量capacity为16(调用reserve)：" << endl;
    a.reserve(16);
    a.show();
    
    cout << "缩小当前长度为3(调用resize)：" << endl;
    a.resize(3);
    a.show();

    cout << "扩容长度为7(调用resize)：" << endl;
    a.resize(7);
    a.show();

    cout << "a[0]:" << a[0] << "  ,  " << "a.at(1):" << a.at(1) << endl;

    cout << "获取第一个元素常引用：" << a.front() << endl;
    cout << "获取最后元素常引用：" << a.back() << endl;

    cout << "清除所有数据(调用clear)"<< endl;
    a.clear();
    a.show();
    return 0;
}